import UIKit


class FTSpinerLayer: CAShapeLayer {
    
    var spinnerColor = UIColor.white {
        didSet {
            strokeColor = spinnerColor.cgColor
        }
    }
    
    init(frame:CGRect) {
        super.init()

        let radius:CGFloat = (frame.height / 2) * 0.5
        self.frame = CGRect(x: 0, y: 0, width: frame.height, height: frame.height)
        let center = CGPoint(x: frame.height / 2, y: bounds.center.y)
        let startAngle = 0 - M_PI_2
        let endAngle = M_PI * 2 - M_PI_2
        let clockwise: Bool = true
        self.path = UIBezierPath(arcCenter: center, radius: radius, startAngle: CGFloat(startAngle), endAngle: CGFloat(endAngle), clockwise: clockwise).cgPath

        self.fillColor = nil
        self.strokeColor = spinnerColor.cgColor
        self.lineWidth = 1
        
        self.strokeEnd = 0.4
        self.isHidden = true
     }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func animation() {
        self.isHidden = false
        let rotate = CABasicAnimation(keyPath: "transform.rotation.z")
        rotate.fromValue = 0
        rotate.toValue = M_PI * 2
        rotate.duration = 0.4
        rotate.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
        
        rotate.repeatCount = HUGE
        rotate.fillMode = kCAFillModeForwards
        rotate.isRemovedOnCompletion = false
        self.add(rotate, forKey: rotate.keyPath)

    }
    
    func stopAnimation() {
        self.isHidden = true
        self.removeAllAnimations()
    }
}


class SpinerLayer :CAShapeLayer ,CAAnimationDelegate{
  
  init(superLayerFrame:CGRect, ballSize:CGFloat, color:UIColor = UIColor.white) {
    super.init()
    
    let radius:CGFloat = (ballSize / 2) * 1.2//1.45
    self.frame = CGRect(x: 0, y: 0, width: superLayerFrame.height, height: superLayerFrame.height)
    let center = CGPoint(x: superLayerFrame.size.width / 2, y: superLayerFrame.origin.y + superLayerFrame.size.height/2)
    let startAngle = 0 - M_PI_2
    let endAngle = (M_PI * 2 - M_PI_2) + M_PI / 8
    let clockwise: Bool = true
    self.path = UIBezierPath(arcCenter: center, radius: radius, startAngle: CGFloat(startAngle), endAngle: CGFloat(endAngle), clockwise: clockwise).cgPath
    
    self.fillColor = nil
    self.strokeColor = color.withAlphaComponent(1).cgColor
    self.lineWidth = 2
    self.lineCap = kCALineCapRound
    
    self.strokeStart = 0
    self.strokeEnd = 0
    self.isHidden = true
    
  }
  
  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }
  
  func animation() {
    self.isHidden = false
    let rotate = CABasicAnimation(keyPath: "transform.rotation.z")
    rotate.fromValue = 0
    rotate.toValue = M_PI * 2
    rotate.duration = 1
    rotate.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
    rotate.repeatCount = HUGE
    rotate.fillMode = kCAFillModeForwards
    rotate.isRemovedOnCompletion = false
    self.add(rotate, forKey: rotate.keyPath)
    
    strokeEndAnimation()
  }
  
  func strokeEndAnimation() {
    let endPoint = CABasicAnimation(keyPath: "strokeEnd")
    endPoint.fromValue = 0
    endPoint.toValue = 1.0
    endPoint.duration = 0.8
    endPoint.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
    endPoint.repeatCount = 1
    endPoint.fillMode = kCAFillModeForwards
    endPoint.isRemovedOnCompletion = false
    endPoint.delegate = self
    self.add(endPoint, forKey: endPoint.keyPath)
  }
  
  func strokeStartAnimation() {
    let startPoint = CABasicAnimation(keyPath: "strokeStart")
    startPoint.fromValue = 0
    startPoint.toValue = 1.0
    startPoint.duration = 0.8
    startPoint.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
    startPoint.repeatCount = 1
    //        startPoint.fillMode = kCAFillModeForwards
    //        startPoint.removedOnCompletion = false
    startPoint.delegate = self
    self.add(startPoint, forKey: startPoint.keyPath)
  }
  
  
  
  func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
    if self.isHidden == false {
      let a:CABasicAnimation = anim as! CABasicAnimation
      if a.keyPath == "strokeStart" {
        strokeEndAnimation()
      }
      else if a.keyPath == "strokeEnd" {
        strokeStartAnimation()
      }
    }
  }
  
  func stopAnimation() {
    self.isHidden = true
    self.removeAllAnimations()
  }
}
